// Scene Manager
// (c) jimon game studio

#ifndef JEH_ISCENEMANAGER
#define JEH_ISCENEMANAGER

#include "jeUnknown.h"
#include "ISerialize.h"
#include "IRender.h"
#include "ISceneNode.h"
#include "jeStl.h"
#include "ICompositor.h"
#include "jePassGroups.h"
#include "ICameraSceneNode.h"
#include "ISpriteSceneNode.h"
#include "IDebugSceneNode.h"
#include "ITextSceneNode.h"
#include "IMeshSceneNode.h"
#include "ILightSceneNode.h"

namespace je
{
	namespace scene
	{
		//! Base SceneManager Compositors
		enum BaseSceneManagerCompositors
		{
			//! Default (no lighting)
			BSMC_DEFAULT,

			//! Forward lighting
			BSMC_FORWARD,

			//! Deferred lighting
			BSMC_DEFERRED
		};

		//! Scene Manager
		class ISceneManager:public je::core::ISerialize
		{
		public:
			//! Destructor
			virtual ~ISceneManager()
			{
			}

			// -------------------------- Create Nodes --------------------------

			//! Create Camera Scene Node
			virtual ICameraSceneNode * CreateCamera(ISceneNode * Parent = NULL) = 0;

			//! Create Sprite Scene Node
			virtual ISpriteSceneNode * CreateSprite(ISceneNode * Parent = NULL) = 0;

			//! Create Pivot Scene Node
			virtual ISceneNode * CreatePivot(ISceneNode * Parent = NULL) = 0;

			//! Create Debug Scene Node
			virtual IDebugSceneNode * CreateDebug(ISceneNode * Parent = NULL) = 0;

			//! Create Text Scene Node
			virtual ITextSceneNode * CreateText(const jeStringd & Text = "",ISceneNode * Parent = NULL) = 0;

			//! Create Mesh Scene Node
			virtual IMeshSceneNode * CreateMeshNode(ISceneNode * Parent = NULL) = 0;

			//! Create Light Scene Node
			virtual ILightSceneNode * CreateLight(ISceneNode * Parent = NULL) = 0;

			// -------------------------- Camera --------------------------

			//! Set Current Camera
			virtual void SetCurrentCamera(ICameraSceneNode * Node) = 0;

			//! Get Current Camera
			virtual ICameraSceneNode * GetCurrentCamera() = 0;

			// -------------------------- Layer Control --------------------------

			//! Set Layer Control
			virtual void SetLayerControl(u1 Enable) = 0;

			//! Get Layer Control
			virtual u1 GetLayerControl() = 0;

			//! Swap Layers
			virtual void SwapLayers(s32 Layer1,s32 Layer2) = 0;

			// -------------------------- Render --------------------------

			//! Return Scene Manager Render
			virtual video::IRender * GetRender() = 0;

			// -------------------------- Get Nodes --------------------------

			//! Return Root
			virtual ISceneNode * GetRoot() = 0;

			//! Get Node By Name
			virtual ISceneNode * GetNodeByName(const jeStringd & NodeName) = 0;

			// -------------------------- Scene Manager Control --------------------------

			//! On Update
			virtual void OnUpdate() = 0;

			//! On Render
			virtual void OnRender() = 0;

			// -------------------------- Rendering Queue Control --------------------------

			//! Register Node In Rendering Queue
			virtual void RegisterNodeInRenderingQueue(ISceneNode * Node,RenderPassGroup Group,RenderPassGroupRights Rights = RPTR_AUTO) = 0;

			//! Register Node In Rendering Queue
			virtual void RegisterNodeInRenderingQueue(ISceneNode * Node,video::jeMaterial * Material)
			{
				RegisterNodeInRenderingQueue(Node,RenderMaterialToRenderPassGroupConverter(Material));
			}

			//! UnRegister Node From Rendering Queue
			virtual void UnRegisterNodeFromRenderingQueue(ISceneNode * Node,RenderPassGroup Group) = 0;

			//! UnRegister Node From Rendering Queue
			virtual void UnRegisterNodeFromRenderingQueue(ISceneNode * Node,video::jeMaterial * Material)
			{
				UnRegisterNodeFromRenderingQueue(Node,RenderMaterialToRenderPassGroupConverter(Material));
			}

			//! Render Queue Groups
			virtual void RenderQueueGroups(u1 RenderAllGroups = true,RenderPassGroup Group = RPG_SOLID) = 0;

			//! Render Queue Object
			virtual void RenderQueueObject(u32 ObjectQueueIndex,RenderPassGroup Group) = 0;

			//! Get Count Of Objects In Queue Group
			virtual u32 GetCountOfObjectsInQueueGroup(RenderPassGroup Group) = 0;

			//! Set Render Pass Group Rights
			virtual void SetRenderPassGroupRights(RenderPassGroup Group,RenderPassGroupRights Rights = RPTR_AUTO) = 0;

			// -------------------------- Compositor Control --------------------------

			//! Add Compositor
			virtual void AddCompositor(ICompositor * Compositor) = 0;

			//! Remove Compositor
			virtual void RemoveCompositor(ICompositor * Compositor) = 0;

			//! Compositor List
			typedef jeList<ICompositor*> CompositorListType;

			//! Get Compositors List
			virtual CompositorListType * GetCompositorList() = 0;

			//! Get Previous Compositor
			virtual ICompositor * GetPreviousCompositor() = 0;

			// -------------------------- Factory Control --------------------------

			//! Scene Node Factory
			typedef jeFactory<ISceneNode> NodeFactoryType;

			//! Return Node Factory
			virtual NodeFactoryType * GetNodeFactory() = 0;

			//! Animator Factory
			typedef jeFactory<IAnimator> AnimatorFactoryType;

			//! Return Animator Factory
			virtual AnimatorFactoryType * GetAnimatorFactory() = 0;

			//! Compositor Factory
			typedef jeFactory<ICompositor> CompositorFactoryType;

			//! Return Compositor Factory
			virtual CompositorFactoryType * GetCompositorFactory() = 0;

			// -------------------------- Lighting Group Control --------------------------

			//! Register Light
			virtual void RegisterLight(ILightSceneNode * Light) = 0;

			//! UnRegister Light
			virtual void UnRegisterLight(ILightSceneNode * Light) = 0;

			//! Light List
			typedef jeList<ILightSceneNode*> LightListType;

			//! Get Light List
			virtual LightListType * GetLightList() = 0;
		};

		//! Create SceneManager
		JE_ENGINE_FUNCTION_API ISceneManager * JE_ENGINE_FUNCTION_CALL CreateSceneManager(video::IRender * Render,BaseSceneManagerCompositors Type);
	}
}

#endif
